/**
 * ReportGear(2011)
 */
package net.abbp.report.export;

import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.PrinterException;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.List;

import net.abbp.core.utils.UnitUtils;
import net.abbp.report.model.Cell;
import net.abbp.report.model.ReportModel;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.reportgear.report.print.FT;
import com.reportgear.report.print.PaperSize;
import com.reportgear.report.print.ReportPage;
import com.reportgear.report.setting.PaperSetting;
import com.reportgear.report.setting.ReportSettings;

/**
 * 报表PDF导出器
 * 
 * @version 1.0 2011-4-19
 * @author <a herf="lexloo@gmail.com">lexloo</a>
 * @since Report 1.0
 */
public class PdfExporter {
    /**
     * PDF导出
     * 
     * @param reportPageIterator 页面表
     * @param settings 配置信息
     * @param fileName 文件名
     */
    public void exportPDF(List<ReportPage> pages, String fileName) {
        if (pages.isEmpty()) {
            return;
        }
        
        ReportSettings settings = pages.get(0).getReportModel().getReportSettings();
        
        PageFormat pageFormat = new PageFormat();

        PaperSetting paperSetting = settings.getPaperSetting();
        PaperSize paperSize = paperSetting.getPaperSize();
        Paper paper = pageFormat.getPaper();

        double ptWidth = UnitUtils.inch2pt(paperSize.getWidth());
        double ptHeight = UnitUtils.inch2pt(paperSize.getHeight());

        paper.setSize(ptWidth, ptHeight);

        paper.setImageableArea(0, 0, ptWidth, ptHeight);
        pageFormat.setPaper(paper);

        pageFormat.setOrientation(paperSetting.getOrientation());
        try {
            this.exportPDF(pages, pageFormat, fileName);
        } catch (PrinterException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * 报表打印
     * 
     * @param pages 页面列表
     * @param format 格式
     * @throws PrinterException
     *             打印异常
     */
    public void exportPDF(List<ReportPage> pages, PageFormat format, String fileName) throws PrinterException {
        if (pages.isEmpty()) {
            return;
        }

        ValueExportManager vem = ValueExportManager.INSTANCE;

        try {
            ReportModel model = pages.get(0).getReportModel();
            Document pdf = new Document(PageSize.A4, 10, 10, 10, 10);
            PdfWriter writer = PdfWriter.getInstance(pdf, new FileOutputStream(fileName));
            pdf.open();

            for (ReportPage page : pages) {
                FT columnFT = page.getColumnFT();
                FT rowFT = page.getRowFT();

                int columns = columnFT.to - columnFT.from;
                PdfPTable table = new PdfPTable(columns);

                float[] widthArr = new float[columns];
                for (int i = 0; i < columns; i++) {
                    widthArr[i] = model.getColumnWidth(columnFT.from + i);
                }
                table.setWidths(widthArr);
                table.setHorizontalAlignment(Element.ALIGN_CENTER);
                for (int row = 0, size = rowFT.to - rowFT.from; row < size; row++) {
                    for (int column = 0; column < columns; column++) {
                        Cell c = model.getCell(column + columnFT.from, row + rowFT.from);
                        IValueExport export;
                        if (c == Cell.EMPTY_CELL) {
                        } else {
                            if (c.getValue() == null) {
                                export = vem.getValueExport(Object.class);
                            } else {
                                export = vem.getValueExport(c.getValue().getClass());
                            }

                            PdfPCell pc = export.cell2PdfCell(c, model);
                            if (c.isMerged()) {
                                pc.setColspan(c.getColumnSpan());
                                pc.setRowspan(c.getRowSpan());
                            }

                            table.addCell(pc);
                        }
                    }
                }

                pdf.add(table);
                pdf.newPage();
            }

            pdf.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }
}
